import { CacheService } from '@services/cache.service';
import { LoadingService } from '@services/loading.service';
import { DataService } from '@services/data.service';
import { PhotoHandleModal } from '@modals/photo-handle/photo-handle';
import { Component, OnInit, Injectable, OnDestroy } from '@angular/core';
import { Router } from '@angular/router';
import { Camera, CameraOptions } from '@ionic-native/camera/ngx';
import { PhotoLibrary } from '@ionic-native/photo-library/ngx';
import { PhotoViewer } from '@ionic-native/photo-viewer/ngx';
import { Media, MediaObject } from '@ionic-native/media/ngx';
import { ActionSheetController, ModalController, Platform, NavController } from '@ionic/angular';
import { File, FileEntry } from '@ionic-native/file/ngx';
import { WebView } from '@ionic-native/ionic-webview/ngx';
import { MediaCapture, MediaFile, CaptureError, CaptureImageOptions, CaptureAudioOptions, CaptureVideoOptions } from '@ionic-native/media-capture/ngx';
import { VideoPlayer } from '@ionic-native/video-player/ngx';
import { VideoEditor } from '@ionic-native/video-editor/ngx';
import { PicUploadService } from '@services/picUpload.service';
import { MyNoteService } from '@services/myNote.service';
import { forkJoin, Observable } from 'rxjs';
import { FileUploadOptions } from '@ionic-native/file-transfer';
@Component({
  selector: 'app-alarm-solve',
  templateUrl: './alarm-solve.component.html',
  styleUrls: ['./alarm-solve.component.scss'],
})
export class AlarmSolveComponent implements OnInit, OnDestroy {
  /**
   * @param data 节点详情
   * @param title 模块标题
   * @param describe 描述
   * @param fileMediaObj 录音文件
   * @param saveRecord 是否保存录音
   * @param images 图片视频数组
   * @param voiceStateTitle 录音状态
   * @param voiceShow 是否显示录音框
   * @param voiceList 录音文件数组
   * @param recordStartTime 录音开始时间
   * @param recordStopTime 录音结束时间
   * @param animateInterval 语音播放动画
   * @param isLook 是否查看
   * @param callback 关闭页面回调函数
   * @param contents 处理详情内容
   * @param load 加载动画
   * @param playVoice 语音文件
   * @param isAdd 是否首次添加内容
   */
  public data: any
  public title: string;
  public describe: string = '';
  public fileMediaObj: MediaObject;
  public saveRecord: boolean;
  public images: Array<any> = [];
  public voiceStateTitle: string;
  public voiceShow: boolean;
  public voiceList: Array<any> = [];
  public recordStartTime: number;
  public recordStopTime: number;
  public animateInterval: any;
  public isLook: boolean;
  public callback: any;
  public contents: any = [];
  public load: any;
  public playVoice: MediaObject;
  public playVoiceIdx: number;
  public isAdd: boolean;
  public disposable: any;
  public isWrite: boolean;
  public volumeInterval: any;
  public volumeTimeout: any;
  public isRorate: boolean = false;
  public checkTimeOur: any;
  public type: boolean
  public alarmInfo: any;

  /**
        * ----------------------------------------------
        * describe : [obj]  指令双向绑定的描述信息
        *    + voiceList: [array]  语音数组
        *         + time: [number] 语音时长
        *         + recordName:[string] 语音资源路径
        *    + photoList: [array]  照片信息
        *         +url  :  [string] 图片路径
        * ----------------------------------------------
        * */
  constructor(
    public loadingService: LoadingService,
    public modalController: ModalController,
    public router: Router,
    public camera: Camera,
    private photoLibrary: PhotoLibrary,
    public photoViewer: PhotoViewer,
    public actionSheetController: ActionSheetController,
    private media: Media,
    private mediaCapture: MediaCapture,
    private file: File,
    private webview: WebView,
    private videoPlayer: VideoPlayer,
    private videoEditor: VideoEditor,
    private picUploadService: PicUploadService,
    private platform: Platform,
    private mynote: MyNoteService,
    private dataService: DataService,
    public navCtrl: NavController,
    public cache: CacheService
  ) {
    const state = this.router.getCurrentNavigation().extras.queryParams;
    this.title = state.title ? state.title : '告警详情';
    this.type = state.type;
    this.callback = state.callback;
    this.data = state.data;
    this.alarmInfo = state.alarmInfo;
    this.isLook = state.isLook;
    this.contents = state.contents ? state.contents : [];
    this.isAdd = state.isAdd;
    this.voiceStateTitle = '手指上滑，取消';
    this.saveRecord = true;
    this.voiceShow = false;
  }

  ngOnInit() {
    this.platform.backButton.subscribe(res => {
      this.disposable.unsubscribe();
      this.loadClose();
      if (this.playVoice) {
        this.playVoice.stop();
        this.playVoice = null;
      }
    })
    if (this.isLook || this.data.procState === 3) {
      this.initContents();
    }
  }
  // 初始化处理描述内容
  initContents() {
    this.contents.forEach((c) => {
      if (c.type === 1) {
        this.describe = c.value
      } else {
        if (c.type === 2 || c.type === 4) {
          this.images.push({ type: 'spin' })
        }
        this.fileDownload(c, c.type)
      }
    })
  }
  // 文件下载
  fileDownload(data, type) {
    const url = data.value.substring(1, data.value.length - 1);
    const service = this.cache.getUrl(15, 200000).serviceAddr;
    const fileType = {
      2: '.jpg',
      3: '.mp3',
      4: '.mp4'
    }
    const path = this.picUploadService.getBasePath() + 'iotOperation/' + new Date().getTime() + fileType[type];
    this.picUploadService.download(service + url, path, true).subscribe(res => {
      if (type === 2) {
        this.updateStoredImages(res.url, 'img', null, true)
      } else if (type === 3) {
        this.voiceList.push({ recordName: res.url, filePath: res.url, time: data.duration, eachVoiceWidth: 55 + data.duration * 5 + 'px' });
      } else if (type === 4) {
        this.createThumbnail(res.url, false);
      }
    })
  }

  ngOnDestroy() {
    this.loadClose();
  }

  loadClose() {
    if (this.load) {
      this.load.then((res) => {
        res.dismiss();
        const callbackFunc = this.callback;
        console.log(callbackFunc);
        callbackFunc(true);
      })
    }
  }

  async presentActionSheet() {
    const actionSheet = await this.actionSheetController.create({
      buttons: [{
        text: '拍照',
        handler: () => {
          this.imageHandler();
        }
      }, {
        text: '录像',
        handler: () => {
          this.videoHandler();
        }
      }, {
        text: '从相册选择',
        handler: () => {
          this.selectPhoto();
        }
      }]
    });
    await actionSheet.present();
  }


  // 拍照操作
  imageHandler() {
    if (this.isCheckImages('img')) {
      return;
    }
    const options: CameraOptions = {
      quality: 100,
      sourceType: this.camera.PictureSourceType.CAMERA,
      destinationType: this.camera.DestinationType.FILE_URI,
      encodingType: this.camera.EncodingType.JPEG,
      mediaType: this.camera.MediaType.ALLMEDIA,
      targetWidth: 1080,
      targetHeight: 1080,
      // allowEdit: true,
      correctOrientation: true
    };

    this.camera.getPicture(options).then((imagePath) => {
      console.log(imagePath);
      this.updateStoredImages(imagePath, 'img');
    }, (err) => {
      // Handle error
    });
  }


  // 视频操作
  videoHandler() {
    console.log('录像 clicked');
    if (this.isCheckImages('video')) {
      return;
    }
    /**
     * @param  limit: 视频数量,
     * @param duration: 时间,
     */
    const options: CaptureVideoOptions = {
      limit: 1,
      duration: 15,
      quality: 20
    }
    this.mediaCapture.captureVideo(options)
      .then(
        (data: any) => {
          for (let i = 0; i < data.length; i++) {
            console.log(data, (data[i].size / 1024).toFixed(2) + 'KB')
            this.createThumbnail(data[i].fullPath);
          }

        },
        (err: CaptureError) => console.error(err)
      );
  }

  // 图片或视频点击跳转
  async mediaClick(i, type) {
    if (type === 'video') {
      this.videoPlay(i)
    }
    const modal = await this.modalController.create({
      component: PhotoHandleModal,
      componentProps: {
        'index': i,
        'isLook': this.isLook,
        'images': this.images,
        'isRorate': this.isRorate
      }
    });
    return await modal.present();
  }

  // 视频点击事件
  videoPlay(i) {
    // Playing a video.
    console.log('videoPlay')
    this.videoPlayer.play(this.images[i].filePath).then(() => {
      console.log('video completed');
    }).catch(err => {
      console.log(err);
    });
  }


  // 构建数组
  /**
   *
   * @param filePath 文件路径
   * @param type （img/video）文件类型
   * @param videoPlaypath 视频播放路径
   * @param path 图片和视频缩略图路径
   */
  updateStoredImages(filePath, type, videoPlaypath?, isDownload?) {
    if (isDownload) {
      this.images.splice(this.images.length - 1, 1);
    }
    const videofilePath = videoPlaypath ? videoPlaypath.startsWith('file://') ? videoPlaypath : `file://${videoPlaypath}` : '';
    const resPath = this.pathForImage(filePath);
    const newEntry = {
      name: name,
      path: resPath,
      filePath: type === 'img' ? filePath : videofilePath,
      type: type,
    };
    this.images = [newEntry, ...this.images];
  }


  // 重定向路径
  pathForImage(img) {
    if (img === null) {
      return '';
    } else {
      const converted = this.webview.convertFileSrc(img);
      return converted;
    }
  }

  // 照片库选择照片
  selectPhoto() {
    console.log('选择照片');
    const options: CameraOptions = {
      quality: 75,
      sourceType: this.camera.PictureSourceType.PHOTOLIBRARY,
      destinationType: this.camera.DestinationType.FILE_URI,
      mediaType: this.camera.MediaType.ALLMEDIA,
    };

    this.camera.getPicture(options).then((imageData) => {
      console.log(imageData);
      const type = imageData.indexOf('mp4') === -1 ? 'img' : 'video'
      if (this.isCheckImages(type)) {
        return;
      }
      if (type === 'img') {
        this.updateStoredImages(imageData, type);
      } else {
        this.createThumbnail(imageData)
      }
    });
  }

  isCheckImages(type) {
    const arr = this.images.filter((item) => { return item.type === type })
    if (arr.length >= 3) {
      this.mynote.MyNotice(type === 'img' ? '最多上传3张图片' : '最多上传3段视频', 1500, null, 'alert-note');
      return true;
    } else {
      return false;
    }
  }

  // 构建缩略图
  /**
   * @param filePath 文件路径
   * @param isTranscodeVideo 是否压缩
   */
  createThumbnail(filePath, isTranscodeVideo = true) {

    this.videoEditor.createThumbnail(
      {
        fileUri: filePath,
        outputFileName: this.generateFileName(),
        atTime: 1,
        width: 75,
        height: 75,
        quality: 100
      }
    ).then((path) => {
      if (isTranscodeVideo) {
        this.images = [{ type: 'spin' }, ...this.images]
        this.transcodeVideo(filePath).then((res) => {
          console.log('压缩视频' + res);
          this.images.shift();
          res.forEach((c, i) => {
            this.updateStoredImages('file://' + path, 'video', c);
          })
        })
      } else {
        this.updateStoredImages('file://' + path, 'video', filePath, true);
      }

    }).catch((err) => {
      console.error(err)
    });
  }

  // 压缩视频
  transcodeVideo(filePath) {
    return this.getVideoInfo([{ filePath: filePath }]).then((videoInfoArr) => {
      const RtArr = [];
      videoInfoArr.forEach((videoInfo, i) => {
        const fileUri = filePath.startsWith('file://') ? filePath : `file://${filePath}`;
        const width: number = 0;
        const height: number = 0;
        const videoPromise = this.videoEditor.transcodeVideo({
          videoBitrate: 4000000,
          fileUri: fileUri,
          outputFileName: `${Date.now()}`,
          outputFileType: this.videoEditor.OutputFileType.MPEG4,
          width: videoInfo.width > 1920 ? 1920 : videoInfo.width,
          height: +(videoInfo.width > 1920 ? 1080 : videoInfo.width / (videoInfo.width / videoInfo.height)).toFixed(0)
        })
        RtArr.push(videoPromise);
      })
      return Promise.all(RtArr);
    })
  }


  // 获取视频信息
  getVideoInfo(data) {
    const arr = [];
    data.forEach((c) => {
      const fileUri = c.filePath.startsWith('file://') ? c.filePath : `file://${c.filePath}`;
      arr.push(this.videoEditor.getVideoInfo({ fileUri }))
    })
    return Promise.all(arr)
  }

  // 生成文件名的方法：yyyymmddhhmmss(月和日不足两位补0)
  complement(n) { return n < 10 ? '0' + n : n }

  generateFileName() {
    const date = new Date();
    return date.getFullYear().toString() + this.complement(date.getMonth() + 1) + this.complement(date.getDate()) + this.complement(date.getHours()) + this.complement(date.getMinutes()) + this.complement(date.getSeconds());
  }

  /***********************************************录音 *******************************************/

  // 开始录音
  startRecord() {

    if (this.voiceList.length >= 3) {
      this.mynote.MyNotice('最多上传3条语音', 1500, null, 'alert-note');
      return;
    } else {
      this.voiceShow = true;

      this.changeVoiceStyle(true);
      this.recordAnimate();
      let src = this.picUploadService.getBasePath(true) + new Date().getTime();
      src += this.platform.is('ios') ? '.m4a' : '.mp3';
      // 创建录音文件
      this.fileMediaObj = this.media.create(src);
      this.fileMediaObj.startRecord();

      this.voiceList.push({ recordName: src, filePath: src });

      // 设定录音开始时间
      this.recordStartTime = new Date().getTime();
      this.checkTimeOur = setInterval(() => {
        const thisTimer = new Date().getTime();
        if (parseInt((((thisTimer - this.recordStartTime) / 1000) + 1).toString(), 10) > 59) {
          this.mynote.MyNotice('录音最长60秒', 1500, null, 'alert-note')
          this.stopRecord();
          clearInterval(this.checkTimeOur);
        }
      }, 1000)
      // 监测录音状态的回调
      this.fileMediaObj.onStatusUpdate.subscribe(status => console.log('录音status' + status));
    }
  }

  // 结束录音(需判断是否保存)
  stopRecord() {
    if (this.voiceShow) {
      console.log('停止录音');
      if (this.checkTimeOur) {
        clearInterval(this.checkTimeOur);
      }
      this.changeVoiceStyle(false);
      this.recordAnimate(true);
      this.fileMediaObj.stopRecord();
      // 设定录音结束时间
      this.recordStopTime = new Date().getTime();
      // 录音成功后回调
      this.fileMediaObj.onSuccess.subscribe(() => {
        console.log('录音成功', this.saveRecord)
        if (this.saveRecord) {
          const currentVoice = this.voiceList[this.voiceList.length - 1];
          currentVoice.time = parseInt((((this.recordStopTime - this.recordStartTime) / 1000) + 1).toString(), 10);
          currentVoice.eachVoiceWidth = 55 + currentVoice.time * 5 + 'px';
          console.log(currentVoice);
        } else {
          // 删除该语音并重置
          console.log('录音取消：', this.voiceList)
          this.voiceList.splice(this.voiceList.length - 1, 1);
          this.fileMediaObj.release();
        }

        this.voiceShow = false;
        this.saveRecord = true;
        this.voiceStateTitle = '手指上滑，取消';
      });
    }
    console.log(this.fileMediaObj);
  }

  // 取消录音
  cancelRecord(e) {
    if (e.deltaY < -70) {
      this.voiceStateTitle = '松开手指，取消';
      this.saveRecord = false;
    } else if (e.deltaY >= 0) {
      this.voiceStateTitle = '手指上滑，取消';
      this.saveRecord = true;
    }
  }

  /**
   * 录音图标背景变化
   * @param isRecord 是否停止录音
   */
  changeVoiceStyle(isRecord) {
    const dom: any = document.getElementsByClassName('alarmSolve-content-voice')[0];
    dom.style.background = isRecord ? '#D2EAFF' : 'transparent';
  }

  /**
   * 录音音量动画
   * @param isClear 是否停止录音,清除定时器
   */
  recordAnimate(isClear = false) {
    let i = 1;
    const animateBoxDom: any = document.getElementsByClassName('voice-state-volumeAnimateBox')[0];
    const animateImgDom: any = document.getElementsByClassName('voice-state-volumeAnimateImg')[0];
    const boxTop = 85;
    if (!isClear) {
      this.animateInterval = setInterval(() => {
        const changeTop = i * 10;
        animateBoxDom.style.top = boxTop - changeTop + 'px';
        animateImgDom.style.top = '-' + (50 - changeTop) + 'px';
        if (i < 5) { i++; } else {
          i = 1;
          animateBoxDom.style.top = '85px';
          animateImgDom.style.top = '-50px';
        }
      }, 500)
    } else {
      clearInterval(this.animateInterval);
      animateBoxDom.style.top = '85px';
      animateImgDom.style.top = '-50px';
    }

  }

  // 语音点击播放
  voiceClick(index, data) {
    if (this.playVoice) {
      this.playVoice.stop();
      this.playVoice = null;
      const dom: any = document.getElementsByClassName('voiceList-item-volume')[this.playVoiceIdx !== index ? this.playVoiceIdx : index];
      dom.style.width = '20px';
      clearInterval(this.volumeInterval);
      clearTimeout(this.volumeTimeout)
      if (this.playVoiceIdx !== index) {
        this.playVoice = this.media.create(data.recordName);
        this.playVoice.play();
        this.voiceAnimate(index, data.time);

      }
      this.playVoiceIdx = index
    } else {
      this.playVoice = this.media.create(data.recordName);
      // play the file
      this.playVoice.play();
      this.voiceAnimate(index, data.time);
      this.playVoiceIdx = index
    }
  }

  /**
   * 音量图标变化动画
   * @param i 索引值
   * @param time 持续时间
   */
  voiceAnimate(i, time) {
    const changeWidth = { 0: 7, 1: 12, 2: 20 }
    let index = 0;
    // 目标dom
    const dom: any = document.getElementsByClassName('voiceList-item-volume')[i];
    // 将所有录音重置
    const allDom: any = document.getElementsByClassName('voiceList-item-volume');
    for (let i = 0; i < allDom.length; i++) {
      allDom[i].style.width = '20px'
    }


    this.volumeInterval = setInterval(() => {
      dom.style.width = changeWidth[index] + 'px';
      if (index === 2) { index = 0; } else { index++ };
    }, 200);

    this.volumeTimeout = setTimeout(() => {
      clearInterval(this.volumeInterval);
      dom.style.width = changeWidth[2] + 'px';
    }, time * 1000)
  }

  // 删除语音
  deleteVoice(index) {
    const file: MediaObject = this.media.create(this.voiceList[index].recordName);
    file.release();
    this.voiceList.splice(index, 1);
  }

  /**********************提交文件*******************/
  doNext() {
    if (this.describe !== '' || this.images.length > 0 || this.voiceList.length > 0) {
      if (this.playVoice) { this.playVoice.stop(); }
      this.load = this.loadingService.load(null);
      const imgList = this.images.filter((item) => { return item.type === 'img' });
      const videoList = this.images.filter((item) => { return item.type === 'video' });
      // 图片上传
      const imgContentArr: any = this.getFileUrl(imgList, 2);
      // 视频上传
      const videoContentArr: any = this.getFileUrl(videoList, 4);
      // 音频上传
      const voiceContentArr: any = this.getFileUrl(this.voiceList, 3);
      const contentArr = [];
      const hasMedia = (imgContentArr.length === 0 && videoContentArr.length === 0 && voiceContentArr.length === 0) ? true : false
      let textContent: any;
      if (this.describe !== '') {
        textContent = {
          contentTypeValue: this.describe,
          contentDataType: 1
        }
      }
      if (hasMedia) {// 无文件上传，只提交描述
        this.getProcessProc([textContent]);
      } else {// 有文件上传，等待所有文件提交完成
        this.disposable = forkJoin([...imgContentArr, ...videoContentArr, ...voiceContentArr]).subscribe((res) => {
          console.log('forkJoin成功' + JSON.stringify(res));
          clearInterval(timeOut);
          // 图片和视频集合
          const allImageLength = imgContentArr.length + videoContentArr.length
          res.forEach((c, i) => {
            const type = i < imgContentArr.length ? 2 : i < allImageLength ? 4 : 3;
            contentArr.push({
              contentTypeValue: c.data.response,
              contentDataType: type,
              duration: type === 3 ? this.voiceList[i - allImageLength].time : 0
            })
          })
          this.getProcessProc(textContent ? [textContent, ...contentArr] : contentArr);
        }, (error) => {
          this.load.then((res) => {
            res.dismiss();
            this.mynote.MyNotice('网络异常，请稍后重试')
          })
        });
        let i = 0;
        // 上传超过60s提示
        const timeOut = setInterval(() => {
          i++;
          if (i > 59) {
            clearInterval(timeOut);
            this.disposable.unsubscribe();
            this.load.then((res) => {
              res.dismiss();
              this.mynote.MyNotice('网络异常，请稍后重试')
            })
          }
        }, 1000)
      }
    } else {
      this.mynote.MyNotice('描述项不能全为空');
    }
  }
  // 上传文件到服务器
  getFileUrl(data, type) {
    let arr = [];
    const mimeType = {
      2: 'image/jpeg',
      4: 'video/mp4',
      3: 'audio/wav'
    };
    const fileName = {
      2: '.jpg',
      4: '.mp4',
      3: '.mp3'
    }
    if (data.length > 0) {
      data.forEach((c) => {
        const options: FileUploadOptions = {
          mimeType: mimeType[type],
          fileName: this.generateFileName() + fileName[type],
          fileKey: 'file',
          params: {
            type: 'iotOperation',
            token: '',
          },
        };
        // const fileUri = c.filePath.startsWith('file://') ? c.filePath : `file://${c.filePath}`;
        arr = [...arr, this.picUploadService.upload(c.filePath, options)];
      })
    }
    return arr;
  }
  // 处理描述提交接口
  getProcessProc(contents) {
    const params = this.type ? {
      businessId: this.data.businessId,
      taskId: this.data.taskId,
      type: this.alarmInfo.type,
      procState: this.data.procState,
      contents: contents
    } : {
        deviceId: this.alarmInfo.deviceId,
        deviceParameterId: this.alarmInfo.deviceParameterId,
        alarmTypeId: this.alarmInfo.alarmTypeId,
        taskId: this.data.taskId,
        procState: this.data.procState,
        contents: contents
      }
    this.dataService.getProcessProc(params, this.isAdd, this.type).subscribe((res: any) => {
      if (res.success) {
        // 提交数据成功，返回上一页
        this.load.then((res) => {
          res.dismiss();
          const callbackFunc = this.callback;
          callbackFunc(true);
          this.navCtrl.pop();
        })
      } else {
        this.load.then((res) => {
          res.dismiss();
          this.mynote.MyNotice('网络异常，请稍后重试')
        })
      }
    })
  }

  inputFocus() {
    this.isWrite = true;
  }

  inputBlur() {
    setTimeout(() => {
      this.isWrite = false;
    }, 200);
  }
  goBack() {
    this.navCtrl.pop();
  }

}
